<html lang="en"><head></head><body>
    <form id="mainForm" method="post" action="https://run.stackblitz.com/api/angular/v1?file=src/app/app.component.html" target="_self"><input type="hidden" name="files[src/app/after-content.component.ts]" value="import { AfterContentChecked, AfterContentInit, Component, ContentChild } from '@angular/core';

import { LoggerService }  from './logger.service';

//////////////////
@Component({
  selector: 'app-child',
  template: '<input [(ngModel)]=&quot;hero&quot;>'
})
export class ChildComponent {
  hero = 'Magneta';
}

//////////////////////
@Component({
  selector: 'after-content',
  template: `
    <div>-- projected content begins --</div>
      <ng-content></ng-content>
    <div>-- projected content ends --</div>`
   + `
    <p *ngIf=&quot;comment&quot; class=&quot;comment&quot;>
      {{comment}}
    </p>
  `
})
export class AfterContentComponent implements AfterContentChecked, AfterContentInit {
  private prevHero = '';
  comment = '';

  // Query for a CONTENT child of type `ChildComponent`
  @ContentChild(ChildComponent) contentChild: ChildComponent;

  constructor(private logger: LoggerService) {
    this.logIt('AfterContent constructor');
  }

  ngAfterContentInit() {
    // contentChild is set after the content has been initialized
    this.logIt('AfterContentInit');
    this.doSomething();
  }

  ngAfterContentChecked() {
    // contentChild is updated after the content has been checked
    if (this.prevHero === this.contentChild.hero) {
      this.logIt('AfterContentChecked (no change)');
    } else {
      this.prevHero = this.contentChild.hero;
      this.logIt('AfterContentChecked');
      this.doSomething();
    }
  }

  // This surrogate for real business logic sets the `comment`
  private doSomething() {
    this.comment = this.contentChild.hero.length > 10 ? `That's a long name` : '';
  }

  private logIt(method: string) {
    let child = this.contentChild;
    let message = `${method}: ${child ? child.hero : 'no'} child content`;
    this.logger.log(message);
  }
  // ...
}

//////////////
@Component({
  selector: 'after-content-parent',
  template: `
  <div class=&quot;parent&quot;>
    <h2>AfterContent</h2>

    <div *ngIf=&quot;show&quot;>` +
     `<after-content>
        <app-child></app-child>
      </after-content>`
+ `</div>

    <h4>-- AfterContent Logs --</h4>
    <p><button (click)=&quot;reset()&quot;>Reset</button></p>
    <div *ngFor=&quot;let msg of logger.logs&quot;>{{msg}}</div>
  </div>
  `,
  styles: ['.parent {background: burlywood}'],
  providers: [LoggerService]
})
export class AfterContentParentComponent {
  show = true;

  constructor(public logger: LoggerService) {
  }

  reset() {
    this.logger.clear();
    // quickly remove and reload AfterContentComponent which recreates it
    this.show = false;
    this.logger.tick_then(() => this.show = true);
  }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/after-view.component.ts]" value="import { AfterViewChecked, AfterViewInit, Component, ViewChild } from '@angular/core';

import { LoggerService }  from './logger.service';

//////////////////
@Component({
  selector: 'app-child-view',
  template: '<input [(ngModel)]=&quot;hero&quot;>'
})
export class ChildViewComponent {
  hero = 'Magneta';
}

//////////////////////
@Component({
  selector: 'after-view',
  template: `
    <div>-- child view begins --</div>
      <app-child-view></app-child-view>
    <div>-- child view ends --</div>`
   + `
    <p *ngIf=&quot;comment&quot; class=&quot;comment&quot;>
      {{comment}}
    </p>
  `
})
export class AfterViewComponent implements  AfterViewChecked, AfterViewInit {
  private prevHero = '';

  // Query for a VIEW child of type `ChildViewComponent`
  @ViewChild(ChildViewComponent) viewChild: ChildViewComponent;

  constructor(private logger: LoggerService) {
    this.logIt('AfterView constructor');
  }

  ngAfterViewInit() {
    // viewChild is set after the view has been initialized
    this.logIt('AfterViewInit');
    this.doSomething();
  }

  ngAfterViewChecked() {
    // viewChild is updated after the view has been checked
    if (this.prevHero === this.viewChild.hero) {
      this.logIt('AfterViewChecked (no change)');
    } else {
      this.prevHero = this.viewChild.hero;
      this.logIt('AfterViewChecked');
      this.doSomething();
    }
  }

  comment = '';

  // This surrogate for real business logic sets the `comment`
  private doSomething() {
    let c = this.viewChild.hero.length > 10 ? `That's a long name` : '';
    if (c !== this.comment) {
      // Wait a tick because the component's view has already been checked
      this.logger.tick_then(() => this.comment = c);
    }
  }

  private logIt(method: string) {
    let child = this.viewChild;
    let message = `${method}: ${child ? child.hero : 'no'} child view`;
    this.logger.log(message);
  }
  // ...
}

//////////////
@Component({
  selector: 'after-view-parent',
  template: `
  <div class=&quot;parent&quot;>
    <h2>AfterView</h2>

    <after-view  *ngIf=&quot;show&quot;></after-view>

    <h4>-- AfterView Logs --</h4>
    <p><button (click)=&quot;reset()&quot;>Reset</button></p>
    <div *ngFor=&quot;let msg of logger.logs&quot;>{{msg}}</div>
  </div>
  `,
  styles: ['.parent {background: burlywood}'],
  providers: [LoggerService]
})
export class AfterViewParentComponent {
  show = true;

  constructor(public logger: LoggerService) {
  }

  reset() {
    this.logger.clear();
    // quickly remove and reload AfterViewComponent which recreates it
    this.show = false;
    this.logger.tick_then(() => this.show = true);
  }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/app.component.ts]" value="import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent { }


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/app.module.ts]" value="import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';

import {
  AfterContentParentComponent,
  AfterContentComponent,
  ChildComponent
} from './after-content.component';

import {
  AfterViewParentComponent,
  AfterViewComponent,
  ChildViewComponent
} from './after-view.component';

import {
  CounterParentComponent,
  MyCounterComponent
} from './counter.component';

import {
  DoCheckParentComponent,
  DoCheckComponent
} from './do-check.component';

import {
  OnChangesParentComponent,
  OnChangesComponent
} from './on-changes.component';

import { PeekABooParentComponent } from './peek-a-boo-parent.component';
import { PeekABooComponent } from './peek-a-boo.component';

import { SpyParentComponent } from './spy.component';
import { SpyDirective } from './spy.directive';

@NgModule({
  imports: [
    BrowserModule,
    FormsModule
  ],
  declarations: [
    AppComponent,
    AfterContentParentComponent,
    AfterContentComponent,
    ChildComponent,
    AfterViewParentComponent,
    AfterViewComponent,
    ChildViewComponent,
    CounterParentComponent,
    MyCounterComponent,
    DoCheckParentComponent,
    DoCheckComponent,
    OnChangesParentComponent,
    OnChangesComponent,
    PeekABooParentComponent,
    PeekABooComponent,
    SpyParentComponent,
    SpyDirective
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/counter.component.ts]" value="import {
  Component, Input,
  OnChanges, SimpleChanges,
} from '@angular/core';

import { LoggerService }  from './logger.service';

@Component({
  selector: 'app-counter',
  template: `
  <div class=&quot;counter&quot;>
    Counter = {{counter}}

    <h5>-- Counter Change Log --</h5>
    <div *ngFor=&quot;let chg of changeLog&quot; mySpy>{{chg}}</div>
  </div>
  `,
  styles: ['.counter {background: LightYellow; padding: 8px; margin-top: 8px}']
})
export class MyCounterComponent implements OnChanges {
  @Input() counter: number;
  changeLog: string[] = [];

  ngOnChanges(changes: SimpleChanges) {

    // Empty the changeLog whenever counter goes to zero
    // hint: this is a way to respond programmatically to external value changes.
    if (this.counter === 0) {
      this.changeLog = [];
    }

    // A change to `counter` is the only change we care about
    let chng = changes['counter'];
    let cur = chng.currentValue;
    let prev = JSON.stringify(chng.previousValue); // first time is {}; after is integer
    this.changeLog.push(`counter: currentValue = ${cur}, previousValue = ${prev}`);
  }
}

@Component({
  selector: 'counter-parent',
  template: `
   <div class=&quot;parent&quot;>
    <h2>Counter Spy</h2>

    <button (click)=&quot;updateCounter()&quot;>Update counter</button>
    <button (click)=&quot;reset()&quot;>Reset Counter</button>

    <app-counter [counter]=&quot;value&quot;></app-counter>

    <h4>-- Spy Lifecycle Hook Log --</h4>
    <div *ngFor=&quot;let msg of spyLog&quot;>{{msg}}</div>
   </div>
  `,
  styles: ['.parent {background: gold;}'],
  providers: [LoggerService]
})
export class CounterParentComponent {
  value: number;
  spyLog: string[] = [];

  private logger: LoggerService;

  constructor(logger: LoggerService) {
    this.logger = logger;
    this.spyLog = logger.logs;
    this.reset();
  }

  updateCounter() {
    this.value += 1;
    this.logger.tick();
  }

  reset() {
    this.logger.log('-- reset --');
    this.value = 0;
    this.logger.tick();
  }
}



/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/do-check.component.ts]" value="/* tslint:disable:forin */
import { Component, DoCheck, Input, ViewChild } from '@angular/core';

class Hero {
  constructor(public name: string) {}
}

@Component({
  selector: 'do-check',
  template: `
  <div class=&quot;hero&quot;>
    <p>{{hero.name}} can {{power}}</p>

    <h4>-- Change Log --</h4>
    <div *ngFor=&quot;let chg of changeLog&quot;>{{chg}}</div>
  </div>
  `,
  styles: [
    '.hero {background: LightYellow; padding: 8px; margin-top: 8px}',
    'p {background: Yellow; padding: 8px; margin-top: 8px}'
  ]
})
export class DoCheckComponent implements DoCheck {
  @Input() hero: Hero;
  @Input() power: string;

  changeDetected = false;
  changeLog: string[] = [];
  oldHeroName = '';
  oldPower = '';
  oldLogLength = 0;
  noChangeCount = 0;

  ngDoCheck() {

    if (this.hero.name !== this.oldHeroName) {
      this.changeDetected = true;
      this.changeLog.push(`DoCheck: Hero name changed to &quot;${this.hero.name}&quot; from &quot;${this.oldHeroName}&quot;`);
      this.oldHeroName = this.hero.name;
    }

    if (this.power !== this.oldPower) {
      this.changeDetected = true;
      this.changeLog.push(`DoCheck: Power changed to &quot;${this.power}&quot; from &quot;${this.oldPower}&quot;`);
      this.oldPower = this.power;
    }

    if (this.changeDetected) {
        this.noChangeCount = 0;
    } else {
        // log that hook was called when there was no relevant change.
        let count = this.noChangeCount += 1;
        let noChangeMsg = `DoCheck called ${count}x when no change to hero or power`;
        if (count === 1) {
          // add new &quot;no change&quot; message
          this.changeLog.push(noChangeMsg);
        } else {
          // update last &quot;no change&quot; message
          this.changeLog[this.changeLog.length - 1] = noChangeMsg;
        }
    }

    this.changeDetected = false;
  }

  reset() {
    this.changeDetected = true;
    this.changeLog = [];
  }
}

@Component({
  selector: 'do-check-parent',
  templateUrl: './do-check-parent.component.html',
  styles: ['.parent {background: Lavender}']
})
export class DoCheckParentComponent {
  hero: Hero;
  power: string;
  title = 'DoCheck';
  @ViewChild(DoCheckComponent) childView: DoCheckComponent;

  constructor() { this.reset(); }

  reset() {
    this.hero = new Hero('Windstorm');
    this.power = 'sing';
    if (this.childView) { this.childView.reset(); }
  }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/logger.service.ts]" value="import { Injectable } from '@angular/core';

@Injectable()
export class LoggerService {
  logs: string[] = [];
  prevMsg = '';
  prevMsgCount = 1;

  log(msg: string)  {
    if (msg === this.prevMsg) {
      // Repeat message; update last log entry with count.
      this.logs[this.logs.length - 1] = msg + ` (${this.prevMsgCount += 1}x)`;
    } else {
      // New message; log it.
      this.prevMsg = msg;
      this.prevMsgCount = 1;
      this.logs.push(msg);
    }
  }

  clear() { this.logs = []; }

  // schedules a view refresh to ensure display catches up
  tick() {  this.tick_then(() => { }); }
  tick_then(fn: () => any) { setTimeout(fn, 0); }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/on-changes.component.ts]" value="/* tslint:disable:forin */
import {
  Component, Input, OnChanges,
  SimpleChanges, ViewChild
} from '@angular/core';

class Hero {
  constructor(public name: string) {}
}

@Component({
  selector: 'on-changes',
  template: `
  <div class=&quot;hero&quot;>
    <p>{{hero.name}} can {{power}}</p>

    <h4>-- Change Log --</h4>
    <div *ngFor=&quot;let chg of changeLog&quot;>{{chg}}</div>
  </div>
  `,
  styles: [
    '.hero {background: LightYellow; padding: 8px; margin-top: 8px}',
    'p {background: Yellow; padding: 8px; margin-top: 8px}'
  ]
})
export class OnChangesComponent implements OnChanges {
  @Input() hero: Hero;
  @Input() power: string;

  changeLog: string[] = [];

  ngOnChanges(changes: SimpleChanges) {
    for (let propName in changes) {
      let chng = changes[propName];
      let cur  = JSON.stringify(chng.currentValue);
      let prev = JSON.stringify(chng.previousValue);
      this.changeLog.push(`${propName}: currentValue = ${cur}, previousValue = ${prev}`);
    }
  }

  reset() { this.changeLog = []; }
}

@Component({
  selector: 'on-changes-parent',
  templateUrl: './on-changes-parent.component.html',
  styles: ['.parent {background: Lavender;}']
})
export class OnChangesParentComponent {
  hero: Hero;
  power: string;
  title = 'OnChanges';
  @ViewChild(OnChangesComponent) childView: OnChangesComponent;

  constructor() {
    this.reset();
  }

  reset() {
    // new Hero object every time; triggers onChanges
    this.hero = new Hero('Windstorm');
    // setting power only triggers onChanges if this value is different
    this.power = 'sing';
    if (this.childView) { this.childView.reset(); }
  }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/peek-a-boo-parent.component.ts]" value="import { Component } from '@angular/core';

import { LoggerService } from './logger.service';

@Component({
  selector: 'peek-a-boo-parent',
  template: `
  <div class=&quot;parent&quot;>
    <h2>Peek-A-Boo</h2>

    <button (click)=&quot;toggleChild()&quot;>
      {{hasChild ? 'Destroy' : 'Create'}} PeekABooComponent
    </button>
    <button (click)=&quot;updateHero()&quot; [hidden]=&quot;!hasChild&quot;>Update Hero</button>

    <peek-a-boo *ngIf=&quot;hasChild&quot; [name]=&quot;heroName&quot;>
    </peek-a-boo>

    <h4>-- Lifecycle Hook Log --</h4>
    <div *ngFor=&quot;let msg of hookLog&quot;>{{msg}}</div>
  </div>
  `,
  styles: ['.parent {background: moccasin}'],
  providers:  [ LoggerService ]
})
export class PeekABooParentComponent {

  hasChild = false;
  hookLog: string[];

  heroName = 'Windstorm';
  private logger: LoggerService;

  constructor(logger: LoggerService) {
    this.logger = logger;
    this.hookLog = logger.logs;
  }

  toggleChild() {
    this.hasChild = !this.hasChild;
    if (this.hasChild) {
      this.heroName = 'Windstorm';
      this.logger.clear(); // clear log on create
    }
    this.hookLog = this.logger.logs;
    this.logger.tick();
  }

  updateHero() {
    this.heroName += '!';
    this.logger.tick();
  }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/peek-a-boo.component.ts]" value="import {
  AfterContentChecked,
  AfterContentInit,
  AfterViewChecked,
  AfterViewInit,
  DoCheck,
  OnChanges,
  OnDestroy,
  OnInit,
  SimpleChanges
} from '@angular/core';
import { Component, Input } from '@angular/core';
import { LoggerService }    from './logger.service';

let nextId = 1;

export class PeekABoo implements OnInit {
  constructor(private logger: LoggerService) { }

  // implement OnInit's `ngOnInit` method
  ngOnInit() { this.logIt(`OnInit`); }

  logIt(msg: string) {
    this.logger.log(`#${nextId++} ${msg}`);
  }
}

@Component({
  selector: 'peek-a-boo',
  template: '<p>Now you see my hero, {{name}}</p>',
  styles: ['p {background: LightYellow; padding: 8px}']
})
// Don't HAVE to mention the Lifecycle Hook interfaces
// unless we want typing and tool support.
export class PeekABooComponent extends PeekABoo implements
             OnChanges, OnInit, DoCheck,
             AfterContentInit, AfterContentChecked,
             AfterViewInit, AfterViewChecked,
             OnDestroy {
  @Input()  name: string;

  private verb = 'initialized';

  constructor(logger: LoggerService) {
    super(logger);

    let is = this.name ? 'is' : 'is not';
    this.logIt(`name ${is} known at construction`);
  }

  // only called for/if there is an @input variable set by parent.
  ngOnChanges(changes: SimpleChanges) {
    let changesMsgs: string[] = [];
    for (let propName in changes) {
      if (propName === 'name') {
        let name = changes['name'].currentValue;
        changesMsgs.push(`name ${this.verb} to &quot;${name}&quot;`);
      } else {
        changesMsgs.push(propName + ' ' + this.verb);
      }
    }
    this.logIt(`OnChanges: ${changesMsgs.join('; ')}`);
    this.verb = 'changed'; // next time it will be a change
  }

  // Beware! Called frequently!
  // Called in every change detection cycle anywhere on the page
  ngDoCheck() { this.logIt(`DoCheck`); }

  ngAfterContentInit() { this.logIt(`AfterContentInit`);  }

  // Beware! Called frequently!
  // Called in every change detection cycle anywhere on the page
  ngAfterContentChecked() { this.logIt(`AfterContentChecked`); }

  ngAfterViewInit() { this.logIt(`AfterViewInit`); }

  // Beware! Called frequently!
  // Called in every change detection cycle anywhere on the page
  ngAfterViewChecked() { this.logIt(`AfterViewChecked`); }

  ngOnDestroy() { this.logIt(`OnDestroy`); }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/spy.component.ts]" value="import { Component } from '@angular/core';

import { LoggerService }  from './logger.service';

@Component({
  selector: 'spy-parent',
  templateUrl: './spy.component.html',
  styles: [
     '.parent {background: khaki;}',
     '.heroes {background: LightYellow; padding: 0 8px}'
  ],
  providers:  [LoggerService]
})
export class SpyParentComponent {
  newName = 'Herbie';
  heroes: string[] = ['Windstorm', 'Magneta'];

  constructor(public logger: LoggerService) {
  }

  addHero() {
    if (this.newName.trim()) {
      this.heroes.push(this.newName.trim());
      this.newName = '';
      this.logger.tick();
    }
  }
  removeHero(hero: string) {
    this.heroes.splice(this.heroes.indexOf(hero), 1);
    this.logger.tick();
  }
  reset() {
    this.logger.log('-- reset --');
    this.heroes = [];
    this.logger.tick();
  }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/spy.directive.ts]" value="import { Directive, OnInit, OnDestroy } from '@angular/core';

import { LoggerService } from './logger.service';

let nextId = 1;

// Spy on any element to which it is applied.
// Usage: <div mySpy>...</div>
@Directive({selector: '[mySpy]'})
export class SpyDirective implements OnInit, OnDestroy {

  constructor(private logger: LoggerService) { }

  ngOnInit()    { this.logIt(`onInit`); }

  ngOnDestroy() { this.logIt(`onDestroy`); }

  private logIt(msg: string) {
    this.logger.log(`Spy #${nextId++} ${msg}`);
  }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/environments/environment.prod.ts]" value="export const environment = {
  production: true
};


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/environments/environment.ts]" value="// This file can be replaced during build by using the `fileReplacements` array.
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.

export const environment = {
  production: false
};

/*
 * For easier debugging in development mode, you can import the following file
 * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
 *
 * This import should be commented out in production mode because it will have a negative impact
 * on performance if an error is thrown.
 */
// import 'zone.js/dist/zone-error';  // Included with Angular CLI.


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/main.ts]" value="import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule);


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/polyfills.ts]" value="/**
 * This file includes polyfills needed by Angular and is loaded before the app.
 * You can add your own extra polyfills to this file.
 *
 * This file is divided into 2 sections:
 *   1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
 *   2. Application imports. Files imported after ZoneJS that should be loaded before your main
 *      file.
 *
 * The current setup is for so-called &quot;evergreen&quot; browsers; the last versions of browsers that
 * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
 * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
 *
 * Learn more in https://angular.io/guide/browser-support
 */

/***************************************************************************************************
 * BROWSER POLYFILLS
 */

/** IE10 and IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js';  // Run `npm install --save classlist.js`.

/**
 * Web Animations `@angular/platform-browser/animations`
 * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
 * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
 */
// import 'web-animations-js';  // Run `npm install --save web-animations-js`.

/**
 * By default, zone.js will patch all possible macroTask and DomEvents
 * user can disable parts of macroTask/DomEvents patch by setting following flags
 * because those flags need to be set before `zone.js` being loaded, and webpack
 * will put import in the top of bundle, so user need to create a separate file
 * in this directory (for example: zone-flags.ts), and put the following flags
 * into that file, and then add the following code before importing zone.js.
 * import './zone-flags.ts';
 *
 * The flags allowed in zone-flags.ts are listed here.
 *
 * The following flags will work for all browsers.
 *
 * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch
 * requestAnimationFrame
 * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
 * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch
 * specified eventNames
 *
 *  in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
 *  with the following flag, it will bypass `zone.js` patch for IE/Edge
 *
 *  (window as any).__Zone_enable_cross_context_check = true;
 *
 */

/***************************************************************************************************
 * Zone JS is required by default for Angular itself.
 */
import 'zone.js/dist/zone'; // Included with Angular CLI.

/***************************************************************************************************
 * APPLICATION IMPORTS
 */


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/assets/sample.css]" value=".parent {
  color: #666;
  margin: 14px 0;
  padding: 8px;
}
input {
  margin: 4px;
  padding: 4px;
}
.comment {
  color: red;
  font-style: italic;
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/styles.css]" value="/* Global Styles */
h1 {
  color: #369;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 250%;
}
h2, h3 {
  color: #444;
  font-family: Arial, Helvetica, sans-serif;
  font-weight: lighter;
}
body {
  margin: 2em;
}
body, input[text], button {
  color: #333;
  font-family: Cambria, Georgia;
}
a {
  cursor: pointer;
  cursor: hand;
}
button {
  font-family: Arial;
  background-color: #eee;
  border: none;
  padding: 5px 10px;
  border-radius: 4px;
  cursor: pointer;
  cursor: hand;
}
button:hover {
  background-color: #cfd8dc;
}
button:disabled {
  background-color: #eee;
  color: #aaa;
  cursor: auto;
}

/* Navigation link styles */
nav a {
  padding: 5px 10px;
  text-decoration: none;
  margin-right: 10px;
  margin-top: 10px;
  display: inline-block;
  background-color: #eee;
  border-radius: 4px;
}
nav a:visited, a:link {
  color: #607D8B;
}
nav a:hover {
  color: #039be5;
  background-color: #CFD8DC;
}
nav a.active {
  color: #039be5;
}

/* everywhere else */
* {
  font-family: Arial, Helvetica, sans-serif;
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/app.component.html]" value="<a id=&quot;top&quot;></a>
<h1>Component Lifecycle Hooks</h1>
<a href=&quot;#hooks&quot;>Peek-a-boo: (most) lifecycle hooks</a><br>
<a href=&quot;#onchanges&quot;>OnChanges</a><br>
<a href=&quot;#docheck&quot;>DoCheck</a><br>
<a href=&quot;#after-view&quot;>AfterViewInit &amp; AfterViewChecked</a><br>
<a href=&quot;#after-content&quot;>AfterContentInit &amp; AfterContentChecked</a><br>
<a href=&quot;#spy&quot;>Spy: directive with OnInit &amp; OnDestroy</a><br>
<a href=&quot;#counter&quot;>Counter: OnChanges + Spy directive</a><br>

<a id=&quot;hooks&quot;></a>
<peek-a-boo-parent></peek-a-boo-parent>
<a href=&quot;#top&quot;>back to top</a>

<a id=&quot;spy&quot;></a>
<spy-parent></spy-parent>
<a href=&quot;#top&quot;>back to top</a>

<a id=&quot;onchanges&quot;></a>
<on-changes-parent></on-changes-parent>
<a href=&quot;#top&quot;>back to top</a>

<a id=&quot;docheck&quot;></a>
<do-check-parent></do-check-parent>
<a href=&quot;#top&quot;>back to top</a>

<a id=&quot;after-view&quot;></a>
<after-view-parent></after-view-parent>
<a href=&quot;#top&quot;>back to top</a>

<a id=&quot;after-content&quot;></a>
<after-content-parent></after-content-parent>
<a href=&quot;#top&quot;>back to top</a>

<a id=&quot;counter&quot;></a>
<counter-parent></counter-parent>
<a href=&quot;#top&quot;>back to top</a>


<!-- 
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->"><input type="hidden" name="files[src/app/do-check-parent.component.html]" value="<div class=&quot;parent&quot;>
  <h2>{{title}}</h2>

  <table>
    <tr><td>Power: </td><td><input [(ngModel)]=&quot;power&quot;></td></tr>
    <tr><td>Hero.name: </td><td><input [(ngModel)]=&quot;hero.name&quot;></td></tr>
  </table>
  <p><button (click)=&quot;reset()&quot;>Reset Log</button></p>

   <do-check [hero]=&quot;hero&quot; [power]=&quot;power&quot;></do-check>
</div>


<!-- 
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->"><input type="hidden" name="files[src/app/on-changes-parent.component.html]" value="<div class=&quot;parent&quot;>
  <h2>{{title}}</h2>

  <table>
    <tr><td>Power: </td><td><input [(ngModel)]=&quot;power&quot;></td></tr>
    <tr><td>Hero.name: </td><td><input [(ngModel)]=&quot;hero.name&quot;></td></tr>
  </table>
  <p><button (click)=&quot;reset()&quot;>Reset Log</button></p>

  <on-changes [hero]=&quot;hero&quot; [power]=&quot;power&quot;></on-changes>
</div>


<!-- 
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->"><input type="hidden" name="files[src/app/spy.component.html]" value="<div class=&quot;parent&quot;>
  <h2>Spy Directive</h2>

  <input [(ngModel)]=&quot;newName&quot; (keyup.enter)=&quot;addHero()&quot;>
  <button (click)=&quot;addHero()&quot;>Add Hero</button>
  <button (click)=&quot;reset()&quot;>Reset Heroes</button>

  <p></p>
  <div *ngFor=&quot;let hero of heroes&quot; mySpy class=&quot;heroes&quot;>
    {{hero}}
  </div>
  <h4>-- Spy Lifecycle Hook Log --</h4>
  <div *ngFor=&quot;let msg of logger.logs&quot;>{{msg}}</div>
</div>


<!-- 
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->"><input type="hidden" name="files[src/index.html]" value="<!DOCTYPE html>
<html lang=&quot;en&quot;>
  <head>
    <title>Angular Lifecycle Hooks</title>
    <base href=&quot;/&quot;>
    <meta charset=&quot;UTF-8&quot;>
    <meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;>
    <link rel=&quot;stylesheet&quot; href=&quot;assets/sample.css&quot;>
  </head>

  <body>
    <app-root></app-root>
  </body>

</html>


<!-- 
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->"><input type="hidden" name="files[angular.json]" value="{
  &quot;$schema&quot;: &quot;./node_modules/@angular/cli/lib/config/schema.json&quot;,
  &quot;version&quot;: 1,
  &quot;newProjectRoot&quot;: &quot;projects&quot;,
  &quot;projects&quot;: {
    &quot;angular.io-example&quot;: {
      &quot;projectType&quot;: &quot;application&quot;,
      &quot;schematics&quot;: {},
      &quot;root&quot;: &quot;&quot;,
      &quot;sourceRoot&quot;: &quot;src&quot;,
      &quot;prefix&quot;: &quot;app&quot;,
      &quot;architect&quot;: {
        &quot;build&quot;: {
          &quot;builder&quot;: &quot;@angular-devkit/build-angular:browser&quot;,
          &quot;options&quot;: {
            &quot;outputPath&quot;: &quot;dist&quot;,
            &quot;index&quot;: &quot;src/index.html&quot;,
            &quot;main&quot;: &quot;src/main.ts&quot;,
            &quot;polyfills&quot;: &quot;src/polyfills.ts&quot;,
            &quot;tsConfig&quot;: &quot;tsconfig.app.json&quot;,
            &quot;assets&quot;: [
              &quot;src/favicon.ico&quot;,
              &quot;src/assets&quot;
            ],
            &quot;styles&quot;: [
              &quot;src/styles.css&quot;
            ],
            &quot;scripts&quot;: []
          },
          &quot;configurations&quot;: {
            &quot;production&quot;: {
              &quot;fileReplacements&quot;: [
                {
                  &quot;replace&quot;: &quot;src/environments/environment.ts&quot;,
                  &quot;with&quot;: &quot;src/environments/environment.prod.ts&quot;
                }
              ],
              &quot;optimization&quot;: true,
              &quot;outputHashing&quot;: &quot;all&quot;,
              &quot;sourceMap&quot;: false,
              &quot;extractCss&quot;: true,
              &quot;namedChunks&quot;: false,
              &quot;aot&quot;: true,
              &quot;extractLicenses&quot;: true,
              &quot;vendorChunk&quot;: false,
              &quot;buildOptimizer&quot;: true,
              &quot;budgets&quot;: [
                {
                  &quot;type&quot;: &quot;initial&quot;,
                  &quot;maximumWarning&quot;: &quot;2mb&quot;,
                  &quot;maximumError&quot;: &quot;5mb&quot;
                }
              ]
            }
          }
        },
        &quot;serve&quot;: {
          &quot;builder&quot;: &quot;@angular-devkit/build-angular:dev-server&quot;,
          &quot;options&quot;: {
            &quot;browserTarget&quot;: &quot;angular.io-example:build&quot;
          },
          &quot;configurations&quot;: {
            &quot;production&quot;: {
              &quot;browserTarget&quot;: &quot;angular.io-example:build:production&quot;
            }
          }
        },
        &quot;extract-i18n&quot;: {
          &quot;builder&quot;: &quot;@angular-devkit/build-angular:extract-i18n&quot;,
          &quot;options&quot;: {
            &quot;browserTarget&quot;: &quot;angular.io-example:build&quot;
          }
        },
        &quot;test&quot;: {
          &quot;builder&quot;: &quot;@angular-devkit/build-angular:karma&quot;,
          &quot;options&quot;: {
            &quot;main&quot;: &quot;src/test.ts&quot;,
            &quot;polyfills&quot;: &quot;src/polyfills.ts&quot;,
            &quot;tsConfig&quot;: &quot;tsconfig.spec.json&quot;,
            &quot;karmaConfig&quot;: &quot;karma.conf.js&quot;,
            &quot;assets&quot;: [
              &quot;src/favicon.ico&quot;,
              &quot;src/assets&quot;
            ],
            &quot;styles&quot;: [
              &quot;src/styles.css&quot;
            ],
            &quot;scripts&quot;: []
          }
        },
        &quot;lint&quot;: {
          &quot;builder&quot;: &quot;@angular-devkit/build-angular:tslint&quot;,
          &quot;options&quot;: {
            &quot;tsConfig&quot;: [
              &quot;tsconfig.app.json&quot;,
              &quot;tsconfig.spec.json&quot;,
              &quot;e2e/tsconfig.json&quot;
            ],
            &quot;exclude&quot;: [
              &quot;**/node_modules/**&quot;
            ]
          }
        },
        &quot;e2e&quot;: {
          &quot;builder&quot;: &quot;@angular-devkit/build-angular:protractor&quot;,
          &quot;options&quot;: {
            &quot;protractorConfig&quot;: &quot;e2e/protractor.conf.js&quot;,
            &quot;devServerTarget&quot;: &quot;angular.io-example:serve&quot;
          },
          &quot;configurations&quot;: {
            &quot;production&quot;: {
              &quot;devServerTarget&quot;: &quot;angular.io-example:serve:production&quot;
            }
          }
        }
      }
    }
  },
  &quot;defaultProject&quot;: &quot;angular.io-example&quot;
}
"><input type="hidden" name="tags[0]" value="angular"><input type="hidden" name="tags[1]" value="example"><input type="hidden" name="tags[2]" value="lifecycle"><input type="hidden" name="tags[3]" value="hooks"><input type="hidden" name="tags[4]" value="OnInit"><input type="hidden" name="tags[5]" value="OnDestroy"><input type="hidden" name="tags[6]" value="OnChange"><input type="hidden" name="tags[7]" value="DoCheck"><input type="hidden" name="tags[8]" value="AfterContentInit"><input type="hidden" name="tags[9]" value="AfterContentChecked"><input type="hidden" name="tags[10]" value="AfterViewInit"><input type="hidden" name="tags[11]" value="AfterViewChecked"><input type="hidden" name="description" value="Angular Example - Lifecycle Hooks"><input type="hidden" name="dependencies" value="{&quot;@angular/animations&quot;:&quot;^8.0.0&quot;,&quot;@angular/common&quot;:&quot;^8.0.0&quot;,&quot;@angular/compiler&quot;:&quot;^8.0.0&quot;,&quot;@angular/core&quot;:&quot;^8.0.0&quot;,&quot;@angular/forms&quot;:&quot;^8.0.0&quot;,&quot;@angular/platform-browser&quot;:&quot;^8.0.0&quot;,&quot;@angular/platform-browser-dynamic&quot;:&quot;^8.0.0&quot;,&quot;@angular/router&quot;:&quot;^8.0.0&quot;,&quot;angular-in-memory-web-api&quot;:&quot;^0.8.0&quot;,&quot;core-js&quot;:&quot;^2.5.4&quot;,&quot;rxjs&quot;:&quot;^6.5.1&quot;,&quot;tslib&quot;:&quot;^1.10.0&quot;,&quot;web-animations-js&quot;:&quot;^2.3.1&quot;,&quot;zone.js&quot;:&quot;~0.10.2&quot;,&quot;jasmine-core&quot;:&quot;~2.99.1&quot;,&quot;jasmine-marbles&quot;:&quot;^0.6.0&quot;}"></form>
    <script>
      var embedded = 'ctl=1';
      var isEmbedded = window.location.search.indexOf(embedded) > -1;

      if (isEmbedded) {
        var form = document.getElementById('mainForm');
        var action = form.action;
        var actionHasParams = action.indexOf('?') > -1;
        var symbol = actionHasParams ? '&' : '?'
        form.action = form.action + symbol + embedded;
      }
      document.getElementById("mainForm").submit();
    </script>
    </body></html>